﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;
using System.Data.OleDb;
using System.Configuration;
using System.Data;
using IsikFx.Project.WcfService.Helpers;
using IsikFx.Project.CommonTypes;
using IsikFx.Project.CommonTypes.Announcement;
using IsikFx.Project.CommonTypes.Fund;
using IsikFx.Project.CommonTypes.User;
using IsikFx.Project.CommonTypes.CRUD;
using IsikFx.Project.CommonTypes.Watchman;
using IsikFx.Project.CommonTypes.FundLog;
using System.IO;
using log4net;
using IsikFx.Project.Utils;
using IsikFx.Project.CommonTypes.Exception;
namespace IsikFx.Project.WcfService
{
    public class Service : IService
    {
        public static ILog logger = LogManager.GetLogger(typeof(Service));
        DbHelper helper = new DbHelper();

        public bool CheckFirstLogin(string domainName)
        {
            logger.Debug("CheckFirstLogin");
            OleDbDataReader reader = helper.GetDataReader(string.Format(QueryConstants.CHECK_FIRST_LOGIN, domainName));

            if (reader != null && reader.HasRows)
            {
                return false;
            }
            reader.Close();
            reader.Dispose();
            return true;
        }

        public bool WcfIsAlive()
        {
            log4net.Config.XmlConfigurator.Configure();
            logger.Debug("Wcf Started..");
            return true;
        }

        public CrudResponseMessage InsertNewFund(string domainName, string fundAmount, int fundDate, int fundMonth, int fundYear)
        {
            int userID = GetUserIDFromDomain(domainName);
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_NEW_FUND, userID, domainName, fundAmount, fundDate, fundMonth, fundYear));
        }

        // Pop-up ta gösterilmeyen fonlamaları göster.
        public FundResponseMessage GetNotShownFunds()
        {
            FundResponseMessage responseMessage = new FundResponseMessage();
            responseMessage.Response = new FundResponse();
            responseMessage.Response.Funds = new List<Fund>();
            try
            {
                DataTable table = helper.GetDataTable(QueryConstants.SELECT_NOT_SHOWN_FUNDS);
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        Fund newFund = new Fund();
                        newFund.ID = Convert.ToInt32(row["ID"]);
                        newFund.UserName = row["UserName"] as string;
                        newFund.UserSurname = row["UserSurname"] as string;
                        newFund.FundAmount = decimal.Parse(row["Amount"] as string);
                        newFund.Currency = row["CurrencyCode"] as string;
                        responseMessage.Response.Funds.Add(newFund);
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMessage.HasError = true;
                responseMessage.ErrorMessage = ex.Message;
            }

            return responseMessage;
        }

        public CrudResponseMessage UpdateShownFunds(int id)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.UPDATE_SHOWN_FUNDS, id));
        }

        public CrudResponseMessage UpdateUserAccount(int id)
        {
            return helper.ExecuteNoneQuery("");
        }

        public int GetUserIDFromDomain(string domainName)
        {
            DataTable rows = helper.GetDataTable(string.Format(QueryConstants.SELECT_USERID, domainName));
            if (rows.Rows.Count > 0)
            {
                return Int32.Parse(rows.Rows[0][0].ToString());
            }
            return 0;
        }

        public CrudResponseMessage UpdateUserRole(int id, int roleType)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.UPDATE_USER_ROLE, id, roleType));
        }

        public CrudResponseMessage InsertNewUser(string name, string surname, int teamId, int role, string domainName)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_NEW_USER, name, surname, teamId, role, domainName));
        }

        public UserResponseMessage GetCurrentUser(string domainName)
        {
            logger.Debug("GetCurrentUser");
            UserResponseMessage userResponseMessage = new UserResponseMessage();
            userResponseMessage.Response = new UserResponse();
            userResponseMessage.Response.User = new List<User>();
            OleDbDataReader reader;
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_USER, domainName));
                if (table != null && table.Rows.Count > 0)
                {
                    DataRow row = table.Rows[0];
                    User user = new User();
                    user.UserID = Convert.ToString(row["ID"]);
                    user.Name = row["User_Name"] as string;
                    user.Surname = row["User_Surname"] as string;
                    user.TeamID = Int32.Parse(row["TeamID"].ToString());
                    user.RoleType = Int32.Parse(row["RoleType"].ToString());
                    reader = helper.GetDataReader(string.Format(QueryConstants.SELECT_TOTAL_FUND_OF_USER, user.UserID));
                    using (reader = helper.GetDataReader(string.Format(QueryConstants.SELECT_TOTAL_FUND_OF_USER, user.UserID)))
                    {
                        while (reader.Read())
                        {
                            user.TotalFundAmount = Convert.ToString(reader["TotalFundAmount"]);
                        }
                    }
                    reader.Close();
                    reader.Dispose();
                    userResponseMessage.Response.User.Add(user);
                }
            }
            catch (Exception ex)
            {
                userResponseMessage.HasError = true;
                userResponseMessage.ErrorMessage = ex.Message;
                ExceptionHelper.HandleException(ex, typeof(Service));
            }
            return userResponseMessage;
        }

        public CrudResponseMessage CreateNewCustomer(int agentID, string customerName, string customerSurname, string loginNo, string accountOpenDate, string firstFundDate, string firstFundAmount, string currencyType)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_CUSTOMER, agentID, customerName, customerSurname, Int32.Parse(loginNo), accountOpenDate, firstFundDate, Int32.Parse(firstFundAmount), currencyType, 0));
        }

        public List<Customer> GetCustomers(int agentID)
        {
            List<Customer> customers = new List<Customer>();
            DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_CUSTOMERS, agentID));

            if (table != null && table.Rows.Count > 0)
            {
                foreach (DataRow row in table.Rows)
                {
                    Customer customer = new Customer();
                    customer.ID = Convert.ToInt32(row["ID"]);
                    customer.AgentID = Convert.ToInt32(row["AgentID"]);
                    customer.Currency = row["CurrencyCode"] as string;
                    customer.CustomerName = row["CustomerName"] as string;
                    customer.CustomerSurname = row["CustomerSurname"] as string;
                    customer.FirstFundAmount = Convert.ToDecimal(row["FirstFundAmount"]);
                    customer.FirstFundDate = row["FirstFundDate"] as string;
                    customer.LoginNo = Convert.ToInt32(row["LoginNo"]);
                    customer.AccountOpenDate = row["AccountOpenDate"] as string;
                    customers.Add(customer);
                }
            }

            return customers;
        }

        public UserResponseMessage GetUsersByRole(int role)
        {
            UserResponseMessage responseMessage = new UserResponseMessage();
            responseMessage.HasError = false;
            responseMessage.Response = new UserResponse();
            responseMessage.Response.User = new List<User>();
            List<User> users = new List<User>();
            OleDbDataReader reader;
            DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_USERS_BY_ROLE, role));
            if (table != null && table.Rows.Count > 0)
            {
                foreach (DataRow row in table.Rows)
                {
                    User user = new User();
                    user.UserID = Convert.ToString(row["ID"]);
                    user.Name = row["User_Name"] as string;
                    user.Surname = row["User_Surname"] as string;
                    user.TeamID = Int32.Parse(row["TeamID"].ToString());
                    user.RoleType = Int32.Parse(row["RoleType"].ToString());
                    using (reader = helper.GetDataReader(string.Format(QueryConstants.SELECT_TOTAL_FUND_OF_USER, user.UserID)))
                    {
                        while (reader.Read())
                        {
                            string value = Convert.ToString(reader["TotalFundAmount"]);
                            user.TotalFundAmount = string.IsNullOrEmpty(value) ? "0" : value;
                        }
                    }
                    responseMessage.Response.User.Add(user);
                }
            }

            return responseMessage;
        }

        public FundResponseMessage GetNewFunds()
        {
            FundResponseMessage responseMessage = new FundResponseMessage();
            responseMessage.Response = new FundResponse();
            responseMessage.Response.Funds = new List<Fund>();
            try
            {
                DataTable table = helper.GetDataTable(QueryConstants.SELECT_NOT_SHOWN_FUNDS);
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        Fund newFund = new Fund();
                        newFund.ID = Convert.ToInt32(row["ID"]);
                        newFund.UserName = row["UserName"] as string;
                        newFund.UserSurname = row["UserSurname"] as string;
                        newFund.FundAmount = decimal.Parse(row["Amount"] as string);
                        newFund.Currency = row["CurrencyCode"] as string;
                        responseMessage.Response.Funds.Add(newFund);
                    }
                }
            }
            catch (Exception ex)
            {
                responseMessage.HasError = true;
                responseMessage.ErrorMessage = ex.Message;
                ExceptionHelper.HandleException(ex, typeof(Service));
            }

            return responseMessage;
        }

        public CrudResponseMessage UpdateFundShownStatus(int id)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.UPDATE_FUND_SHOWN_STATUS, id));
        }


        public bool Test()
        {
            return true;
        }


        public CrudResponseMessage UpdateAgentGoal(int agentID, string fundGoal, string accountGoal, string currencyType, bool insert)
        {
            if (insert)
                return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_GOALS, agentID, Convert.ToInt32(fundGoal), Convert.ToInt32(accountGoal), currencyType));
            else
                return helper.ExecuteNoneQuery(string.Format(QueryConstants.UPDATE_GOALS, Convert.ToInt32(fundGoal), Convert.ToInt32(accountGoal), currencyType, agentID));
        }

        public Goal GetAgentGoal(int agentID)
        {
            Goal goal = new Goal();
            DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_GOALS, agentID));

            if (table != null && table.Rows.Count > 0)
            {
                foreach (DataRow row in table.Rows)
                {
                    goal.FundGoal = Convert.ToInt32(row["FundGoal"]);
                    goal.AccountGoal = Convert.ToInt32(row["AccountGoal"]);
                    goal.FundType = row["Currency"].ToString();
                }
            }

            return goal;
        }


        public GoalProgress GetGoalProgress(int agentID)
        {
            GoalProgress goalProgress = new GoalProgress();
            DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_GOAL_PROGRESS, agentID));
            if (table != null && table.Rows.Count > 0)
            {
                foreach (DataRow row in table.Rows)
                {
                    if (!row.IsNull("Total") && !row.IsNull("Count"))
                    {
                        goalProgress.TotalFundAmount = Convert.ToInt32(row["Total"]);
                        goalProgress.AccountCount = Convert.ToInt32(row["Count"]);
                    }
                    else
                    {
                        return null;
                    }
                }
            }

            return goalProgress;
        }


        public AnnouncementResponseMessage GetActiveAnnouncementsAsUser(int roleType)
        {
            AnnouncementResponseMessage responseMsg = new AnnouncementResponseMessage();
            responseMsg.Response = new AnnouncementResponse();
            List<Announcement> list = new List<Announcement>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_USER_ANNOUNCEMETS, roleType));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        Announcement announcement = new Announcement();
                        announcement.ID = Convert.ToInt32(row["ID"]);
                        announcement.AdminID = Convert.ToInt32(row["AdminID"]);
                        announcement.AnnouncementContent = row["Announcement"] as string;
                        announcement.AnnouncementID = row["AnnouncementID"] as string;
                        announcement.AnnouncementTitle = row["AnnouncementTitle"] as string;
                        announcement.CreateDate = row["CreateDate"] as string;
                        announcement.IsDeleted = Convert.ToInt32(row["IsDeleted"]);
                        list.Add(announcement);
                    }

                    responseMsg.Response.AnnouncementArray = list;
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            return responseMsg;
        }


        public AnnouncementResponseMessage GetActiveAnnouncementsAsAdmin(int adminID)
        {
            AnnouncementResponseMessage responseMsg = new AnnouncementResponseMessage();
            responseMsg.Response = new AnnouncementResponse();
            List<Announcement> list = new List<Announcement>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_ADMIN_ANNOUNCEMETS, adminID));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        Announcement announcement = new Announcement();
                        announcement.ID = Convert.ToInt32(row["ID"]);
                        announcement.AdminID = Convert.ToInt32(row["AdminID"]);
                        announcement.AnnouncementContent = row["Announcement"] as string;
                        announcement.AnnouncementID = row["AnnouncementID"] as string;
                        announcement.AnnouncementTitle = row["AnnouncementTitle"] as string;
                        announcement.CreateDate = row["CreateDate"] as string;
                        announcement.IsDeleted = Convert.ToInt32(row["IsDeleted"]);
                        announcement.RoleType = Convert.ToInt32(row["RoleType"]);
                        list.Add(announcement);
                    }

                    responseMsg.Response.AnnouncementArray = list;
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            return responseMsg;
        }


        public CrudResponseMessage InsertAnnouncement(int adminID, string announcementID, string announcementTitle, string announcement, string createDate, int roleType)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_NEW_ANNOUNCEMENT, adminID, announcementID, announcementTitle, announcement, createDate, roleType));
        }


        public CrudResponseMessage ResetGoals()
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.RESET_GOALS, "USD"));
        }


        public CrudResponseMessage DeleteAnnouncement(int id)
        {
            return helper.ExecuteNoneQuery(String.Format(QueryConstants.DELETE_ANNOUNCEMETS, id));
        }


        public CrudResponseMessage UpdateWatchmenTable(List<Watchman> watchManList)
        {
            if (watchManList == null && watchManList.Count == 0)
                return new CrudResponseMessage() { HasError = true, ErrorMessage = "Güncellenmek istenen liste bulunamadı." };

            CrudResponseMessage deleteResponse = new CrudResponseMessage();
            deleteResponse = helper.ExecuteNoneQuery(String.Format(QueryConstants.DELETE_WATCHMEN, watchManList[0].WatchmanDate));
            if (deleteResponse.HasError)
            {
                return deleteResponse;
            }
            else
            {
                CrudResponseMessage totalInsertResponse = new CrudResponseMessage();
                foreach (Watchman watchMan in watchManList)
                {
                    CrudResponseMessage insertResponse = new CrudResponseMessage();
                    insertResponse = helper.ExecuteNoneQuery(String.Format(QueryConstants.INSERT_WATCHMEN, watchMan.UserId, watchMan.AdminID, watchMan.WatchmanName, watchMan.WatchmanSurname, watchMan.WatchmanDate));
                    if (insertResponse.HasError)
                    {
                        insertResponse.ErrorMessage = watchMan.WatchmanName + " nöbetçisini eklerken hata oluştu.";
                        return insertResponse;
                    }
                    totalInsertResponse = insertResponse;
                }
                return totalInsertResponse;
            }
        }

        public WatchmanResponseMessage GetWatchmenList(string watchmanDate)
        {
            WatchmanResponseMessage responseMsg = new WatchmanResponseMessage();
            responseMsg.Response = new WatchmanResponse();
            List<Watchman> list = new List<Watchman>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_WATCHMEN, watchmanDate));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        Watchman watchman = new Watchman();
                        //watchman.ID = Convert.ToInt32(row["ID"]);
                        watchman.UserId = Convert.ToInt32(row["UserID"]);
                        watchman.AdminID = Convert.ToInt32(row["AdminID"]);
                        watchman.WatchmanName = row["WatchmanName"] as string;
                        watchman.WatchmanSurname = row["WatchmanSurname"] as string;
                        watchman.WatchmanDate = row["WatchmanDate"] as string;
                        if (watchman.WatchmanDate == watchmanDate)
                            list.Add(watchman);
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            responseMsg.Response.WatchmanList = list;
            return responseMsg;
        }


        public FundLogResponseMessage GetMinusFundLogs(string userID, string date)
        {
            FundLogResponseMessage responseMsg = new FundLogResponseMessage();
            responseMsg.Response = new FundLogResponse();
            List<FundLog> list = new List<FundLog>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_MINUS_FUNDS, userID, date, 1));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        FundLog fundLog = new FundLog();
                        fundLog.FundAmount = row["FundAmount"] as string;
                        fundLog.FundDate = row["FundDate"] as string;
                        fundLog.FundTime = row["FundTime"] as string;
                        fundLog.IsFundOut = Convert.ToInt32(row["IsFundOut"]);
                        list.Add(fundLog);
                    }

                    responseMsg.Response.FundLogs = list;
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            return responseMsg;
        }

        public FundLogResponseMessage GetPlusFundLogs(string userID, string date)
        {
            FundLogResponseMessage responseMsg = new FundLogResponseMessage();
            responseMsg.Response = new FundLogResponse();
            List<FundLog> list = new List<FundLog>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_PLUS_FUNDS, userID, date, 0));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        FundLog fundLog = new FundLog();
                        fundLog.FundAmount = row["FundAmount"] as string;
                        fundLog.FundDate = row["FundDate"] as string;
                        fundLog.FundTime = row["FundTime"] as string;
                        fundLog.IsFundOut = Convert.ToInt32(row["IsFundOut"]);
                        list.Add(fundLog);
                    }

                    responseMsg.Response.FundLogs = list;
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            return responseMsg;
        }

        public FundLogResponseMessage GetAllFundLogs(string userID, string date)
        {
            FundLogResponseMessage responseMsg = new FundLogResponseMessage();
            responseMsg.Response = new FundLogResponse();
            List<FundLog> list = new List<FundLog>();
            try
            {
                DataTable table = helper.GetDataTable(string.Format(QueryConstants.SELECT_ALL_FUNDS, userID, date));
                if (table != null && table.Rows.Count > 0)
                {
                    foreach (DataRow row in table.Rows)
                    {
                        FundLog fundLog = new FundLog();
                        fundLog.FundAmount = row["FundAmount"] as string;
                        fundLog.FundDate = row["FundDate"] as string;
                        fundLog.FundTime = row["FundTime"] as string;
                        fundLog.IsFundOut = Convert.ToInt32(row["IsFundOut"]);
                        list.Add(fundLog);
                    }

                    responseMsg.Response.FundLogs = list;
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMsg.HasError = true;
                responseMsg.ErrorMessage = ex.Message;
            }
            return responseMsg;
        }

        public CrudResponseMessage InsertFundLog(string userID, string fundAmount, int isFundOut, string fundDate, string fundTime)
        {
            return helper.ExecuteNoneQuery(string.Format(QueryConstants.INSERT_FUNDLOG, userID, fundAmount, isFundOut, fundDate, fundTime));
        }


        public CrudResponseMessage SaveUsersPhoto(string fileName, byte[] stream)
        {
            CrudResponseMessage responseMessage = new CrudResponseMessage();
            responseMessage.Response = new CrudResponse();
            string directory = System.Configuration.ConfigurationManager.AppSettings["PhotoFilePath"] as string;
            string tempPath = Path.GetTempPath();

            try
            {
                if (string.IsNullOrEmpty(fileName) || stream == null || stream.Length == 0)
                {
                    responseMessage.HasError = true;
                    responseMessage.ErrorMessage = "Invalid Arguments";
                }
                else
                {
                    if (File.Exists(fileName))
                    {
                        responseMessage.HasError = true;
                        responseMessage.ErrorMessage = "Dosya Mevcut";
                    }
                    else
                    {
                        if (!Directory.Exists(directory))
                        {
                            Directory.CreateDirectory(directory);
                        }

                        File.WriteAllBytes(Path.Combine(directory, fileName), stream);
                        responseMessage.HasError = false;
                        responseMessage.Response.AffectedRows = 1;
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.HandleException(ex, typeof(Service));
                responseMessage.HasError = true;
                responseMessage.ErrorMessage = ex.Message;
            }

            return responseMessage;
        }
    }
}
